﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Threading;
using System.Xml;
using System.Windows.Navigation;
using System.Xml.Linq;
using System.Diagnostics;
using Microsoft.Phone.Tasks;
using System.IO.IsolatedStorage;
using System.Xml.Serialization;

namespace OpenGovernment
{
    public class OpenData
    {
        XNamespace ns2 = "http://diavgeia.gov.gr/schema/api/diavgeia-decision-0.1";
        XNamespace ns3 = "http://diavgeia.gov.gr/schema/model/diavgeia-decision-0.1";

        String typesUri = "http://opendata.diavgeia.gov.gr/api/types.xml";
        String tagsUri = "http://opendata.diavgeia.gov.gr/api/tags.xml";
        String unitsUri = "http://opendata.diavgeia.gov.gr/api/units.xml";
        String signersUri = "http://opendata.diavgeia.gov.gr/api/signers?org=";

        int ready = 0;
        public static string blank = "     ";

        public delegate void DoneHandler();
        public event DoneHandler Done;

        List<value> types = new List<value>();
        List<value> tags = new List<value>();
        List<value> orgs = new List<value>();
        List<value> signers = new List<value>();
        List<value> units = new List<value>();
        public List<String> GetTypes()
        {
            return (from value item in types
                    select item.label).ToList<String>();
        }
        public List<String> GetTags()
        {
            return (from value item in tags
                    select item.label).ToList<String>();
        }
        public string getLatin(string label)
        {
            return orgs.Single<value>(item => item.label == label).latin;
        }
        public int getOrgId(string label)
        {
            return orgs.Single<value>(item => item.label == label).id;
        }
        public string getOrgFromId(int orgId)
        {
            try
            {
                return orgs.Single<value>(item => item.id == orgId).label;
            }
            catch (InvalidOperationException) { return "unknown"; }
        }
        public string getSignerFromId(int Id)
        {
            try
            {
                return signers.Single<value>(item => item.id == Id).label;
            }
            catch (InvalidOperationException) { return "unknown"; }
        }
        public int getTagId(string label)
        {
            return tags.Single<value>(item => item.label == label).id;
        }
        public int GetTypeID(string label)
        {
            return types.Single<value>(item => item.label == label).id;
        }
        public int getSignerId(string label)
        {
            return signers.Single<value>(item => item.person.title + " " + item.person.secondname + " " + item.person.firstname == label).id;
        }
        public List<String> GetOrgs()
        {
            return (from value item in orgs
                    select item.label).ToList<String>();
        }
        public List<person> GetSigners()
        {
            return (from value item in signers
                    select item.person).ToList<person>();
        }
        public List<String> GetUnits()
        {
            return (from value item in units
                    select item.label).ToList<String>();
        }
        public static List<String> AddBlank(List<String> list)
        {
            List<String> result = new List<String>();
            result.Add(blank);
            result.AddRange(list);
            return result;
        }
        public int gets = 3;
        string unitsOrgLatin;
        private void Ready()
        {
            ready++;
            if (ready == gets)
            {
                ready = 0;
                Done();
                if(gets == 3)
                {
                    gets = 2;
                }
            }
        }
        struct value
        {
            public string label;
            public int id;
            public string latin;
            public person person;
        }
        public struct person
        {
            public string firstname;
            public string secondname;
            public string title;            
        }
        public OpenData()
        {
            new GetData(typesUri).GotData += new GetData.GotDataHandler(GotTypes);
            new GetData(tagsUri).GotData += new GetData.GotDataHandler(GotTags);

            orgs = GetList(XElement.Load("diavgeia.xml"),"organization");
            Ready();
        }

        public void GetForOrg(string org)
        {
            GetSigners(org);
            GetUnits(org);
        }
        private List<value> GetList(XElement xe, string field)
        {
            Thread.CurrentThread.CurrentCulture =
                 new System.Globalization.CultureInfo("el-GR");
            if (field == "organization")
            {
                return (from y in xe.Descendants(ns3 + "organization")
                        select new value() { label = y.Element(ns3 + "label").Value, id = Convert.ToInt32(y.Attribute("uid").Value), latin = y.Element(ns3 + "latinName").Value }).ToList<value>();
            }
            if (field == "unit")
            {             
                List<value> x = new List<value>();
                foreach(XElement y in xe.Descendants(ns3 + "organization"))
                {
                    if (y.Element(ns3 + "latinName").Value == unitsOrgLatin)
                    {
                        x.AddRange(from unit in y.Descendants(ns3 + "unit") 
                                   select new value() { label = unit.Element(ns3 + "label").Value, id = Convert.ToInt32(unit.Attribute("uid").Value) });
                    }
                }
                return x;
            }
            if (field == "signer")
            {
                return (from y in xe.Descendants(ns3 + field)
                        select new value() { person = new person() { firstname = y.Element(ns3 + "firstName").Value, secondname = y.Element(ns3 + "lastName").Value, title = y.Element(ns3 + "title").Value }, id = Convert.ToInt32(y.Attribute("uid").Value) }).ToList<value>();
        
            }
            return (from y in xe.Descendants(ns3 + field)
             select new value() { label = y.Element(ns3 + "label").Value, id = Convert.ToInt32(y.Attribute("uid").Value) }).ToList<value>();
        }
        private void GetSigners(string latin)
        {
            new GetData(signersUri+latin).GotData += new GetData.GotDataHandler(GotSigners);
        }
        private void GetUnits(string latin)
        {
            unitsOrgLatin = latin;
            new GetData(unitsUri).GotData += new GetData.GotDataHandler(GotUnits);
        }
        private void GotTypes(XElement xe)
        {
            types = GetList(xe, "decisionType");
            Ready();
        }
        private void GotTags(XElement xe)
        {
            tags = GetList(xe, "tag");
            Ready();
        }
        private void GotUnits(XElement xe)
        {
            units = GetList(xe, "unit");
            Ready();
        }
        private void GotSigners(XElement xe)
        {
            signers = GetList(xe, "signer");
            Ready();
        }
    }
    
}
